package example.ilm.model;

import ilm.framework.assignment.model.AssignmentState;
import ilm.framework.domain.DomainModel;

import java.awt.geom.Point2D;
import java.util.List;

public class IlmDomainModel extends DomainModel {

    public GeometricElement getGeometricElementByName(AssignmentState state, String name) {
        return (GeometricElement)(state.getFromName(name));
    }

    public void addGeometricElement(AssignmentState state, GeometricElement geometricElement) {
        state.add(geometricElement);
    }

    public boolean removeGeometricElement(AssignmentState state, Workspace workspace, GeometricElement geometricElement) {
    	if(workspace.getFocusedGeometricElement() == geometricElement)
    		workspace.unsetFocusedGeometricElement();
        return state.remove(geometricElement);
    }

    public void translateGeometricElement(AssignmentState state, GeometricElement geometricElement, double dx, double dy) {
        Point2D p = geometricElement.getPosition();
        geometricElement.setPosition(p.getX() + dx, p.getY() + dy);
        state.setStateChanged(geometricElement);
    }

    public void scaleShape(AssignmentState state, Shape shape, double scale) {
        shape.setScale(shape.getScale() * scale);
        state.setStateChanged(shape);
    }

    public void rotatePolygon(AssignmentState state, Polygon polygon, double angle) {
        polygon.setAngle(polygon.getAngle() + angle);
        state.setStateChanged(polygon);
    }

    public void bringForwards(AssignmentState state, Workspace workspace, GeometricElement geometricElement) {
        workspace.bringForwards(geometricElement);
        state.setStateChanged(null);
    }

    public void sendBackwards(AssignmentState state, Workspace workspace, GeometricElement geometricElement) {
        workspace.sendBackwards(geometricElement);
        state.setStateChanged(null);
    }

    public void bringToFront(AssignmentState state, Workspace workspace, GeometricElement geometricElement) {
        workspace.bringToFront(geometricElement);
        state.setStateChanged(null);
    }

    public void sendToBack(AssignmentState state, Workspace workspace, GeometricElement geometricElement) {
        workspace.sendToBack(geometricElement);
        state.setStateChanged(null);
    }
    
    public void setWorkspaceGeometricElementList(AssignmentState state, Workspace workspace, List ordering) {
    	workspace.setGeometricElementList(ordering);
    	state.setStateChanged(null);
    }


    // ----------------------------------------------

    /**
     * This counter is used to define unique names for the objects being created
     */
    private int _objCount = 1;

    /**
     * Adds an ObjectSubString to the assignment state with the parameter
     * substring
     * 
     * @param state
     * @param substring
     * 
     * @see example.ilm.model.ActionAddSubString, it is called when this action
     *      is executed
     * @see example.ilm.model.ActionRemoveSubString, it is called when this
     *      action is undone
     */
    public void AddSubString(AssignmentState state, String substring) {
        String name = substring + _objCount;
        _objCount++;
        ObjectSubString objectSubString = new ObjectSubString(name, substring, substring);
        state.add(objectSubString);
    }

    /**
     * Remove the last ObjectSubString from the assignment state
     * 
     * @param state
     * 
     * @see example.ilm.model.ActionAddSubString, it is called when this action
     *      is undone
     * @see example.ilm.model.ActionRemoveSubString, it is called when this
     *      action is executed
     */
    public void RemoveSubString(AssignmentState state) {
        state.remove(state.getList().size() - 1);
    }

    /**
     * @return an assignment state representing a new blank assignment. In this
     *         case, a blank assignment has no objects in it.
     */
    public AssignmentState getNewAssignmentState() {
        return new AssignmentState();
    }

    /**
     * @return the result of the comparison between the student state with the
     *         expected state.
     */
    public float AutomaticChecking(AssignmentState student, AssignmentState expected) {
        if (student.getList().size() != expected.getList().size()) {
            return 0;
        }
        int grade = 0;
        for (int i = 0; i < student.getList().size(); i++) {
            if (student.get(i).equals(expected.get(i))) {
                grade++;
            }
        }
        return grade / student.getList().size();
    }
}
